package com.hourupdate.network.rss;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.log4j.Logger;

public class RssFeedParser {
	static final Logger logger = Logger.getLogger(RssFeedParser.class);
	private static final String TITLE = "title";
	private static final String DESCRIPTION = "description";
	private static final String LINK = "link";
	private static final String ITEM = "item";
	private static final String PUB_DATE = "pubDate";
	
	boolean _DESCRIPTION = false;
	boolean _TITLE = false;
	boolean _LINK = false;
	boolean _ITEM = false;
	boolean _PUB_DATE = false;
	boolean _IMAGE = false;
	
	private HttpURLConnection connection;

	public RssFeedParser(String feedUrl, boolean chkProxy) {
		try {
			if(chkProxy){
				Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.cgd.go.th", 8080));
				this.connection = (HttpURLConnection)new URL(feedUrl).openConnection(proxy);
				this.connection.connect();
			}else{
				this.connection = (HttpURLConnection)new URL(feedUrl).openConnection();
				this.connection.connect();
			}
		} catch (IOException e) {
			logger.error(e.getMessage());
		}
	}

	public Feed readFeed() {
		Feed feed = null;
		try {
			boolean isFeedHeader = true;
			// Set header values intial to the empty string
			String description = "";
			String title = "";
			String link = "";
			String pubdate = "";
			String image = "";
			
			// First create a new XMLInputFactory
			XMLInputFactory inputFactory = XMLInputFactory.newInstance();
			// Setup a new streamReader
			XMLStreamReader streamReader = inputFactory.createXMLStreamReader(new java.io.StringReader(read()));
			// Read the XML document
			while (streamReader.hasNext()) {
				streamReader.next();
				if (streamReader.isStartElement()) {
					if (streamReader.getLocalName().equalsIgnoreCase(ITEM)){
						if (isFeedHeader) {
							isFeedHeader = false;
							feed = new Feed();
							description = "";
							link = "";
							title = "";
							pubdate = "";
							image = "";
						}
						_ITEM = true;
					}else if(streamReader.getLocalName().equalsIgnoreCase(TITLE)){
						_TITLE = true;
					}else if(streamReader.getLocalName().equalsIgnoreCase(DESCRIPTION)){
						_DESCRIPTION = true;
					}else if(streamReader.getLocalName().equalsIgnoreCase(LINK)){
						_LINK = true;
					}else if(streamReader.getLocalName().equalsIgnoreCase(PUB_DATE)){
						_PUB_DATE = true;
					}else if(streamReader.getLocalName().equalsIgnoreCase("thumbnail170x115")){
						_IMAGE = true;
					}else if(streamReader.getLocalName().equalsIgnoreCase("enclosure")){
						if(streamReader.getAttributeLocalName(0).equalsIgnoreCase("url")){
							image = streamReader.getAttributeValue(0);
						}
					}
				}else if(streamReader.isCharacters()){
					if(_TITLE){
						title = getCharacterData(streamReader);
					}else if(_DESCRIPTION){
						description = getCharacterData(streamReader);
					}else if(_LINK){
						link = getCharacterData(streamReader);
					}else if(_PUB_DATE){
						pubdate = getCharacterData(streamReader);
					}else if(_IMAGE){
						image = getCharacterData(streamReader);
					}					
				} else if (streamReader.isEndElement()) {
					if (streamReader.getLocalName().equalsIgnoreCase(ITEM)) {
						FeedMessage message = new FeedMessage();
						message.setDescription(description);
						message.setLink(link);
						message.setTitle(title);
						message.setPubDate(pubdate);
						message.setImage(image);
//						logger.info(message);
						feed.getMessages().add(message);
						_ITEM = false;
					}
					_TITLE = false;
					_DESCRIPTION = false;
					_LINK = false;
					_PUB_DATE = false;
					_IMAGE = false;
				}
			}
		} catch (XMLStreamException e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return feed;
	}

	private String getCharacterData(XMLStreamReader streamReader){
		String result = "";
		if (streamReader.isCharacters()) {
			result = streamReader.getText().replaceAll("</?[a-z A-Z].*>", "").trim();
		}
		return result;
	}

	private String read() {
		BufferedReader br = null;
		StringBuilder sb = new StringBuilder();
		String line;
		try {
			br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
			while ((line = br.readLine()) != null) {
				sb.append(line);
			}
			
		} catch (IOException e) {
			logger.error(e.getMessage());
		}finally{
			if(br != null){
				try{
					br.close();
				} catch (IOException e){
					logger.error(e.getMessage());
				}
			}
		}
		System.out.println(sb.toString());
		return sb.toString().replaceAll("\n", "").replaceFirst("^([\\W]+)<","<");
	}
}
